package com.jinke.api.modules.ums.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.jinke.api.common.api.CommonPage;
import com.jinke.api.common.api.CommonResult;
import com.jinke.api.common.exception.Asserts;
import com.jinke.api.common.util.CommonUtil;
import com.jinke.api.common.util.FileUtil;
import com.jinke.api.common.util.Global;
import com.jinke.api.common.util.MathTool;
import com.jinke.api.domain.AdminUserDetails;
import com.jinke.api.modules.app.controller.StaticController;
import com.jinke.api.modules.app.controller.param.CompanySellerProfitParam;
import com.jinke.api.modules.app.controller.param.SellerUserDayParam;
import com.jinke.api.modules.app.enums.*;
import com.jinke.api.modules.app.model.BalanceLog;
import com.jinke.api.modules.app.model.Order;
import com.jinke.api.modules.app.request.SysMessageCreateRequest;
import com.jinke.api.modules.app.response.TrackSummaryVO;
import com.jinke.api.modules.app.response.UmsAdminExport;
import com.jinke.api.modules.app.response.UserOrderCountVO;
import com.jinke.api.modules.app.service.BalanceLogService;
import com.jinke.api.modules.app.service.OrderService;
import com.jinke.api.modules.app.service.SysMessageService;
import com.jinke.api.modules.app.util.InvitationCodeUtil;
import com.jinke.api.modules.app.util.JavaMailUntil;
import com.jinke.api.modules.app.util.OssUtil;
import com.jinke.api.modules.ums.dto.*;
import com.jinke.api.modules.ums.mapper.UmsAdminLoginLogMapper;
import com.jinke.api.modules.ums.mapper.UmsAdminMapper;
import com.jinke.api.modules.ums.mapper.UmsResourceMapper;
import com.jinke.api.modules.ums.mapper.UmsRoleMapper;
import com.jinke.api.modules.ums.model.ChannelPlatform;
import com.jinke.api.modules.ums.model.*;
import com.jinke.api.modules.ums.request.AllotChannelRequest;
import com.jinke.api.modules.ums.request.UserReleaseEarnestRequest;
import com.jinke.api.modules.ums.service.*;
import com.jinke.api.modules.ums.util.IPUtil;
import com.jinke.api.modules.ums.vo.SellerVo;
import com.jinke.api.modules.ums.vo.SimpleUser;
import com.jinke.api.modules.ums.vo.UmsAdminVO;
import com.jinke.api.modules.ums.vo.UserChannelVO;
import com.jinke.api.security.util.AdminUserUtil;
import com.jinke.api.security.util.JwtTokenUtil;
import com.jinke.api.security.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.BeanUtil;
import net.dreamlu.mica.core.utils.StringUtil;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 后台管理员管理Service实现类
 * Created by macro on 2018/4/26.
 */
@Service
@Slf4j
public class UmsAdminServiceImpl extends ServiceImpl<UmsAdminMapper, UmsAdmin> implements UmsAdminService {
    private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminServiceImpl.class);
    @Resource
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private UmsAdminLoginLogMapper loginLogMapper;
    @Autowired
    private UmsRoleMapper roleMapper;
    @Autowired
    private UmsResourceMapper resourceMapper;
    @Autowired
    private UmsAdminRoleRelationService adminRoleRelationService;
    @Autowired
    private UserChannelService userChannelService;
    @Resource
    private UserChannelService channelUserService;
    @Resource
    private ChannelPlatformService channelPlatformService;
    @Resource
    private ChannelService channelService;
    @Resource
    private ChannelCarrierService channelCarrierService;
    @Resource
    private StaticController staticController;
    @Resource
    private OrderService orderService;
    @Autowired
    private SysMessageService sysMessageService;
    @Resource
    private OssUtil ossUtil;
    @Resource
    private PlatformTransactionManager transactionManager;
    @Resource
    BalanceLogService balanceLogService;

    private final static String WZ_EMAIL = "admin@163.com";
    private final static String WZ_EMAIL2 = "403379112@qq.com";
    private final static String NINA_EMAIL = "945629909@qq.com";

    @Override
    public int updateRole(Integer adminId, List<Integer> roleIds) {
        int count = roleIds == null ? 0 : roleIds.size();
        //先删除原来的关系
        QueryWrapper<UmsAdminRoleRelation> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UmsAdminRoleRelation::getAdminId, adminId);
        adminRoleRelationService.remove(wrapper);
        //建立新关系
        if (!CollectionUtils.isEmpty(roleIds)) {
            List<UmsAdminRoleRelation> list = new ArrayList<>();
            for (Integer roleId : roleIds) {
                UmsAdminRoleRelation roleRelation = new UmsAdminRoleRelation();
                roleRelation.setAdminId(adminId);
                roleRelation.setRoleId(roleId);
                list.add(roleRelation);
            }
            adminRoleRelationService.saveBatch(list);
        }
        getCacheService().delResourceList(adminId);
        return count;
    }

    @Override
    public UmsAdmin getAdminByKeyword(String keyword) {

        QueryWrapper<UmsAdmin> wrapper = new QueryWrapper<>();
        wrapper.lambda().or(umsAdminLambdaQueryWrapper -> {
            umsAdminLambdaQueryWrapper.eq(UmsAdmin::getUsername, keyword);
        }).or(umsAdminLambdaQueryWrapper -> {
            umsAdminLambdaQueryWrapper
                    .eq(UmsAdmin::getPhone, keyword);
        }).or(umsAdminLambdaQueryWrapper -> {
            umsAdminLambdaQueryWrapper.eq(UmsAdmin::getEmail, keyword);
        });
        List<UmsAdmin> adminList = list(wrapper);
        if (adminList != null && adminList.size() > 0) {
            return adminList.get(0);
        }
        return null;
    }

    @Override
    public UmsAdmin register(UmsAdminParam umsAdminParam) {
        UmsAdmin umsAdmin = new UmsAdmin();
        BeanUtils.copyProperties(umsAdminParam, umsAdmin);
        umsAdmin.setCreateTime(new Date());
        umsAdmin.setInvitationCode(InvitationCodeUtil.create());
        umsAdmin.setProfitRate(BigDecimal.valueOf(1));
        umsAdmin.setStatus(1);
        //查询是否有相同用户名的用户
        QueryWrapper<UmsAdmin> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UmsAdmin::getUsername, umsAdmin.getUsername());
        List<UmsAdmin> umsAdminList = list(wrapper);
        if (umsAdminList.size() > 0) {
            Asserts.fail("用户名已存在");
            return null;
        }
        if (list(new LambdaQueryWrapper<UmsAdmin>()
                .eq(UmsAdmin::getEmail, umsAdmin.getEmail())).size() > 0) {
            Asserts.fail("The email already exists");
            return null;
        }
        if (list(new LambdaQueryWrapper<UmsAdmin>()
                .eq(UmsAdmin::getPhone, umsAdmin.getPhone())).size() > 0) {
            Asserts.fail("The phone already exists");
            return null;
        }
        //将密码进行加密操作
        String encodePassword = passwordEncoder.encode(umsAdmin.getPassword());
        umsAdmin.setPassword(encodePassword);
        baseMapper.insert(umsAdmin);

        // 设置角色
        updateRole(umsAdmin.getId(), Arrays.asList(1));
        return umsAdmin;
    }

    @Override
    public String login(String username, String password) {
        String token = null;
        //密码需要客户端加密后传递
        try {
            AdminUserDetails userDetails = loadUserByUsername(username);
            if (!passwordEncoder.matches(password, userDetails.getPassword())) {
                Asserts.fail("密码不正确");
            }
            if (!userDetails.isEnabled()) {
                Asserts.fail("请联系管理员开启/激活账户");
            }
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            token = jwtTokenUtil.generateToken(userDetails);
//            updateLoginTimeByUsername(username);
            insertLoginLog(username);


            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();

            UmsAdmin umsAdmin = userDetails.getUmsAdmin();
            UmsAdmin update = new UmsAdmin();
            update.setId(umsAdmin.getId());
            update.setLoginTime(new Date());
            updateById(update);
        } catch (AuthenticationException e) {
            LOGGER.warn("登录异常:{}", e.getMessage());
        }
        return token;
    }

    @Override
    public String generateTokenByUserId(Integer userId) {
        String token = null;
        //密码需要客户端加密后传递
        try {

            UserDetails userDetails = loadUserById(userId);
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            token = jwtTokenUtil.generateToken(userDetails);
        } catch (AuthenticationException e) {
            LOGGER.warn("登录异常:{}", e.getMessage());
        }
        return token;
    }

    /**
     * 添加登录记录
     *
     * @param username 用户名
     */
    private void insertLoginLog(String username) {
        UmsAdmin admin = getAdminByKeyword(username);
        if (admin == null) return;
        UmsAdminLoginLog loginLog = new UmsAdminLoginLog();
        loginLog.setAdminId(admin.getId());
        loginLog.setCreateTime(new Date());
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        loginLog.setIp(IPUtil.getIpAddr(request));
        loginLogMapper.insert(loginLog);
    }

    /**
     * 根据用户名修改登录时间
     */
    private void updateLoginTimeByUsername(String username) {
        UmsAdmin record = new UmsAdmin();
        record.setLoginTime(new Date());
        QueryWrapper<UmsAdmin> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UmsAdmin::getUsername, username);
        update(record, wrapper);
    }

    @Override
    public String refreshToken(String oldToken) {
        return jwtTokenUtil.refreshHeadToken(oldToken);
    }

    @Override
    public Page<UmsAdmin> list(UmsAdminListParam umsAdminListParam) {
        Integer pageNum = umsAdminListParam.getPageNum();
        Integer pageSize = umsAdminListParam.getPageSize();
        MemberType memberType = umsAdminListParam.getMemberType();
        List<String> keywords = umsAdminListParam.getKeywords();

        UmsAdmin userInfo = AdminUserUtil.getUserInfo();
        Page<UmsAdmin> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<UmsAdmin> wrapper = new LambdaQueryWrapper<>();

        String sellerRealName = umsAdminListParam.getSellerRealName();
        if (StringUtils.isNotBlank(sellerRealName)) {
            Set<Integer> sellerIds = list(new LambdaQueryWrapper<UmsAdmin>().like(UmsAdmin::getRealName, sellerRealName)).stream().map(UmsAdmin::getId)
                    .collect(Collectors.toSet());
            if (CollectionUtils.isEmpty(sellerIds)) {
                sellerIds = new HashSet<Integer>() {
                };
                sellerIds.add(-1);
            }
            wrapper.in(UmsAdmin::getSellerId, sellerIds);
        }

        // 仅admin自己可见
        if (userInfo.getId() != 3) {
            wrapper.ne(UmsAdmin::getId, 3);
        }
        wrapper.eq(memberType != null, UmsAdmin::getMemberType, memberType);
        wrapper.orderByDesc(UmsAdmin::getId);
        if (!CollectionUtils.isEmpty(keywords)) {

            // 创建一个外部条件，用于包含所有关键字的 OR 连接
            wrapper.and(wp -> {
                for (String keyword : keywords) {
                    wp.or(w -> {
                        w.like(UmsAdmin::getEmail, keyword).or().like(UmsAdmin::getRealName, keyword);
                    });
                }
            });
        }
        if (userInfo.isSeller()) { // 如果是销售只能看自己或者自己相关的数据
            Integer sellerId = userInfo.getId();
            wrapper.and(wp -> {
                wp.eq(UmsAdmin::getSellerId, sellerId).or().eq(UmsAdmin::getId, sellerId);
            });
        }
        return page(page, wrapper);
    }

    /**
     * 用户管理查询
     *
     * @param request
     * @return
     */
    @Override
    public CommonResult<CommonPage<UmsAdminVO>> listVo(UmsAdminListParam request) {
        Page<UmsAdmin> adminList = list(request);
        if (CollectionUtil.isEmpty(adminList.getRecords())) {
            return CommonResult.success();
        }
        CommonPage<UmsAdmin> umsAdminCommonPage = CommonPage.restPage(adminList);
        CommonPage<UmsAdminVO> umsAdminVOCommonPage = new CommonPage<>();
        BeanUtils.copyProperties(umsAdminCommonPage, umsAdminVOCommonPage);

        List<UserChannelVO> userChannelVOS = new ArrayList<>();
        List<UmsAdmin> umsAdmins = umsAdminCommonPage.getList();
        Set<Integer> userIds = umsAdmins.stream().map(UmsAdmin::getId).collect(Collectors.toSet());
        List<UserChannel> userChannels = channelUserService.list(new LambdaQueryWrapper<UserChannel>().in(UserChannel::getUserId, userIds));

        Map<Integer, UmsAdmin> sellerMap = new HashMap<>();
        Set<Integer> selleIds = umsAdmins.stream().map(UmsAdmin::getSellerId).filter(Objects::nonNull).collect(Collectors.toSet());
        if (CollectionUtil.isNotEmpty(selleIds)) {
            sellerMap = list(new LambdaQueryWrapper<UmsAdmin>()
                    .in(UmsAdmin::getId, selleIds)
                    .select(UmsAdmin::getId, UmsAdmin::getRealName, UmsAdmin::getEmail)
            ).stream().collect(Collectors.toMap(UmsAdmin::getId, Function.identity()));
        }

        Map<Integer, List<UserChannelVO>> userChannelMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(userChannels)) {
            Set<Integer> channelIds = userChannels.stream().map(UserChannel::getChannelId).collect(Collectors.toSet());
            List<Channel> channels = channelService.list(new LambdaQueryWrapper<Channel>().in(Channel::getId, channelIds));
            Map<Integer, Channel> channelMap = channels.stream()
                    .collect(Collectors.toMap(Channel::getId, Function.identity()));

            Set<Integer> channelPlatformIds = userChannels.stream().map(UserChannel::getChannelPlatformId).collect(Collectors.toSet());
            Map<Integer, String> channelPlatformMap = channelPlatformService.list(new LambdaQueryWrapper<ChannelPlatform>()
                    .in(ChannelPlatform::getId, channelPlatformIds))
                    .stream().collect(Collectors.toMap(ChannelPlatform::getId, ChannelPlatform::getChannelPlatformName));

            Set<Integer> channelCarrierIds = userChannels.stream().map(UserChannel::getChannelCarrierId).collect(Collectors.toSet());
            Map<Integer, String> channelCarrierMap = channelCarrierService.list(new LambdaQueryWrapper<ChannelCarrier>()
                    .in(ChannelCarrier::getId, channelCarrierIds))
                    .stream().collect(Collectors.toMap(ChannelCarrier::getId, ChannelCarrier::getChannelCarrierName));

            for (UserChannel userChannel : userChannels) {
                UserChannelVO userChannelVO = new UserChannelVO();
                BeanUtils.copyProperties(userChannel, userChannelVO);
                Channel channel = channelMap.get(userChannelVO.getChannelId());
                if (channel != null) {
                    userChannelVO.setChannelName(channel.getChannelName());
                    userChannelVO.setChannelPlatFormName(channelPlatformMap.get(channel.getChannelPlatformId()));
                    userChannelVO.setChannelCarrierName(channelCarrierMap.get(channel.getChannelCarrierId()));
                }
                userChannelVOS.add(userChannelVO);
            }
            userChannelMap = userChannelVOS.stream().collect(Collectors.groupingBy(UserChannelVO::getUserId));
        }

        Map<Integer, List<UserChannelVO>> finalUserChannelMap = userChannelMap;
        Map<Integer, UmsAdmin> finalSellerMap = sellerMap;
        List<UmsAdminVO> umsAdminVOS = umsAdmins.stream().map(x -> {
            UmsAdminVO umsAdminVO = new UmsAdminVO();
            umsAdminVO.setUserChannels(finalUserChannelMap.get(x.getId()));
            BeanUtils.copyProperties(x, umsAdminVO);

            List<UmsRole> roleList = getRoleList(x.getId());
            if (CollUtil.isNotEmpty(roleList)) {
                List<String> roles = roleList.stream().map(UmsRole::getName).collect(Collectors.toList());
                umsAdminVO.setRoles(roles);
            }

            Integer sellerId = x.getSellerId();
            if (sellerId != null) {
                UmsAdmin umsAdmin = finalSellerMap.get(sellerId);
                if (umsAdmin != null) {
                    umsAdminVO.setSeller(umsAdmin);
                }
            }

            return umsAdminVO;
        }).collect(Collectors.toList());
        umsAdminVOCommonPage.setList(umsAdminVOS);
        return CommonResult.success(umsAdminVOCommonPage);
    }

    /**
     * 修改用户信息
     *
     * @param id
     * @param admin
     * @return
     */
    @Override
    public boolean update(Integer id, UmsAdmin admin) {
        admin.setId(id);
        UmsAdmin rawAdmin = getById(id);
        if (rawAdmin.getPassword().equals(admin.getPassword())) {
            //与原加密密码相同的不需要修改
            admin.setPassword(null);
        } else {
            //与原加密密码不同的需要加密修改
            if (StrUtil.isEmpty(admin.getPassword())) {
                admin.setPassword(null);
            } else {
                admin.setPassword(passwordEncoder.encode(admin.getPassword()));
            }
        }
        boolean success = updateById(admin);

        List<UserChannel> userChannels = admin.getUserChannels();
        //更新授权渠道的设置
        if (!CollectionUtils.isEmpty(userChannels)) {
            for (UserChannel userChannel : userChannels) {
                userChannelService.update(new LambdaUpdateWrapper<UserChannel>()
                        .eq(UserChannel::getId, userChannel.getId())
                        .eq(UserChannel::getUserId, id)
                        .set(UserChannel::getRate, userChannel.getRate())
                        .set(UserChannel::getPrice, userChannel.getPrice())
                        .set(userChannel.getIsBest() == 1, UserChannel::getPlatformRate, userChannel.getPlatformRate())
                        .set(userChannel.getIsBest() == 0, UserChannel::getPlatformRate, null)
                        .set(UserChannel::getIsBest, userChannel.getIsBest())
                );
            }
        }
        return success;
    }

    @Override
    public boolean delete(Integer id) {
        boolean success = removeById(id);
        return success;
    }

    @Override
    public int updatePassword(UpdateAdminPasswordParam param) {
        if (StrUtil.isEmpty(param.getUsername())
                || StrUtil.isEmpty(param.getOldPassword())
                || StrUtil.isEmpty(param.getNewPassword())) {
            return -1;
        }
        QueryWrapper<UmsAdmin> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UmsAdmin::getUsername, param.getUsername());
        List<UmsAdmin> adminList = list(wrapper);
        if (CollUtil.isEmpty(adminList)) {
            return -2;
        }
        UmsAdmin umsAdmin = adminList.get(0);
        if (!passwordEncoder.matches(param.getOldPassword(), umsAdmin.getPassword())) {
            return -3;
        }
        umsAdmin.setPassword(passwordEncoder.encode(param.getNewPassword()));
        updateById(umsAdmin);
        return 1;
    }

    @Override
    public AdminUserDetails loadUserByUsername(String username) {
        //获取用户信息
        UmsAdmin admin = getAdminByKeyword(username);
        if (admin != null) {

            List<UmsResource> resourceList = getResourceList(admin.getId());

            return new AdminUserDetails(admin, resourceList);
        }
        throw new UsernameNotFoundException("用户名或密码错误");
    }

    @Override
    public AdminUserDetails loadUserById(Integer id) {
        //获取用户信息
        UmsAdmin admin = getById(id);
        if (admin != null) {

            List<UmsResource> resourceList = getResourceList(admin.getId());

            return new AdminUserDetails(admin, resourceList);
        }
        throw new UsernameNotFoundException("用户名或密码错误");
    }

    public List<UmsResource> getResourceList(Integer adminId) {
        List<UmsResource> resourceList = getCacheService().getResourceList(adminId);
        if (CollUtil.isNotEmpty(resourceList)) {
            return resourceList;
        }
        resourceList = resourceMapper.getResourceList(adminId);
        if (CollUtil.isNotEmpty(resourceList)) {
            getCacheService().setResourceList(adminId, resourceList);
        }
        return resourceList;
    }

    public UmsAdminCacheService getCacheService() {
        return SpringUtil.getBean(UmsAdminCacheService.class);
    }

    @Override
    public Map<Integer, SimpleUser> getMaps(List<Integer> ids) {
        if (ids == null || ids.isEmpty()) {
            return null;
        }
        LambdaQueryWrapper<UmsAdmin> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .select(UmsAdmin::getUsername, UmsAdmin::getRealName, UmsAdmin::getEmail, UmsAdmin::getIcon, UmsAdmin::getId)
                .in(UmsAdmin::getId, ids);
        List<UmsAdmin> users = list(queryWrapper);
        List<SimpleUser> simpleUsers = new ArrayList<>();
        users.forEach(x -> {
            SimpleUser user = new SimpleUser();
            BeanUtils.copyProperties(x, user);
            simpleUsers.add(user);
        });
        return simpleUsers.stream().collect(Collectors.toMap(SimpleUser::getId, Function.identity()));
    }

    @Override
    public List<Integer> searchIds(String keyword) {
        if (StringUtils.isEmpty(keyword)) {
            return null;
        }
        LambdaQueryWrapper<UmsAdmin> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.likeRight(UmsAdmin::getUsername, keyword).
                or().likeRight(UmsAdmin::getNickName, keyword).
                or().likeRight(UmsAdmin::getEmail, keyword).
                or().eq(UmsAdmin::getId, keyword).last("LIMIT 1000");
        List<UmsAdmin> list = list(queryWrapper);
        if (list.size() <= 0) {
            // 返回一个0id的用户，让调用这一层的业务查不到数据
            UmsAdmin emptyUser = new UmsAdmin();
            emptyUser.setId(0);
            list.add(emptyUser);
        }
        return list.stream().map(UmsAdmin::getId).collect(Collectors.toList());
    }

    @Override
    // @Cacheable(value = "user:rate", key = "#userId")
    public BigDecimal getRate(Integer userId) {
        UmsAdmin umsAdmin = getById(userId);
        if (umsAdmin != null) {
            if (umsAdmin.getProfitRate() != null) {

                if (umsAdmin.getProfitRate().compareTo(BigDecimal.ZERO) == 0) {
                    //如果有没设置的返回1
                    return BigDecimal.ONE;

                } else {
                    return umsAdmin.getProfitRate();
                }
            } else {
                //默认为1
                return BigDecimal.ONE;
            }
        }
        return BigDecimal.ZERO;
    }

    @Override
    public BigDecimal getBalance(Integer id) {

        return getById(id).getBalance();
    }

    @Override
    public List<UmsRole> getRoleList(Integer adminId) {
        return roleMapper.getRoleList(adminId);
    }

    @Override
    public CommonResult<CommonPage<Channel>> allotChannel(AllotChannelRequest request) {
        List<Integer> userIds = request.getUserId();
        if (CollectionUtil.isEmpty(userIds)) {
            return CommonResult.failed("请选择用户");
        }


        AllotChannelType allotChannelType = request.getAllotChannelType();

        if (allotChannelType == null) {
            return CommonResult.failed("请选择操作类型");
        }
        List<Integer> channelIds = request.getChannelIds();
        if (CollectionUtil.isEmpty(channelIds)) {
            return CommonResult.failed("请选择服务");
        }

        if (AllotChannelType.COVER.equals(allotChannelType)) {
            // 移除之前的
            channelUserService.remove(new LambdaQueryWrapper<UserChannel>().in(UserChannel::getUserId, userIds));
            List<UserChannel> channelUsers = new ArrayList();
            for (Integer userId : userIds) {

                List<Channel> channels = channelService.list(new LambdaQueryWrapper<Channel>().in(Channel::getId, channelIds));
                Map<Integer, Channel> channelMap = channels.stream()
                        .collect(Collectors.toMap(Channel::getId, Function.identity()));
                channelUsers.addAll(channelIds.stream()
                        .filter(y -> {
                            return channelMap.get(y) != null;
                        })
                        .map(x -> {
                            Channel channel = channelMap.get(x);
                            UserChannel channelUser = new UserChannel();
                            channelUser.setUserId(userId);
                            channelUser.setChannelCarrierId(channel.getChannelCarrierId());
                            channelUser.setChannelPlatformId(channel.getChannelPlatformId());
                            channelUser.setChannelId(x);
                            return channelUser;
                        }).collect(Collectors.toSet()));
            }


            channelUserService.saveBatch(channelUsers);
        } else if (AllotChannelType.ADD.equals(allotChannelType)) {


            List<UserChannel> channelUsers = new ArrayList();
            for (Integer userId : userIds) {

                Set<Integer> oldChannels = channelUserService.list(new LambdaQueryWrapper<UserChannel>()
                        .eq(UserChannel::getUserId, userId)
                ).stream().map(UserChannel::getChannelId).collect(Collectors.toSet());

                Set<Integer> difference = new HashSet<>(channelIds);
                difference.removeAll(oldChannels);
                if (CollectionUtil.isEmpty(difference)) {
                    continue;
                }
                List<Channel> channels = channelService.list(new LambdaQueryWrapper<Channel>().in(Channel::getId, difference));
                Map<Integer, Channel> channelMap = channels.stream()
                        .collect(Collectors.toMap(Channel::getId, Function.identity()));
                channelUsers.addAll(difference.stream().map(x -> {
                    UserChannel channelUser = new UserChannel();
                    channelUser.setUserId(userId);
                    channelUser.setChannelCarrierId(channelMap.get(x).getChannelCarrierId());
                    channelUser.setChannelPlatformId(channelMap.get(x).getChannelPlatformId());
                    channelUser.setChannelId(x);
                    return channelUser;
                }).collect(Collectors.toSet()));
            }


            channelUserService.saveBatch(channelUsers);
        } else if (AllotChannelType.REDUCE.equals(allotChannelType)) {
            // 移除之前的
            channelUserService.remove(new LambdaQueryWrapper<UserChannel>()
                    .in(UserChannel::getUserId, userIds)
                    .in(UserChannel::getChannelId, channelIds));
        }

        return CommonResult.success();
    }

    /**
     * 员工下载
     *
     * @param request
     * @return
     */
    @Override
    public CommonResult<String> down(UmsAdminListParam request) {
        request.setPageSize(999999);
        request.setPageNum(1);
        //用户管理查询
        CommonResult<CommonPage<UmsAdminVO>> commonPageCommonResult = listVo(request);
        List<UmsAdminVO> records = commonPageCommonResult.getData().getList();
        if (CollectionUtil.isNotEmpty(records)) {

            List<UmsAdminExport> balanceLogExports = records.stream().map(x -> {
                UmsAdminExport umsAdminExport = new UmsAdminExport();
                BeanUtil.copy(x, umsAdminExport);
                UmsAdmin seller = x.getSeller();
                if (seller != null) {
                    umsAdminExport.setSeller(seller.getRealName());
                }
                umsAdminExport.setRole(StringUtil.join(x.getRoles(), ","));
                List<UserChannelVO> userChannels = x.getUserChannels();
                if (CollectionUtil.isNotEmpty(userChannels)) {
                    Set<String> channels = userChannels.stream().map(UserChannelVO::getChannelName).collect(Collectors.toSet());
                    umsAdminExport.setChannels(StringUtil.join(channels, "\r\n"));
                }
                umsAdminExport.setStatus(1 == x.getStatus() ? "启用" : "禁用");
                if (BigDecimal.ZERO.compareTo(x.getBalance()) > 0) {
                    //当前信用额度=信用额度+余额（余额为负数时相当于减掉11）
                    umsAdminExport.setCurCreditBalance(x.getCreditBalance().add(x.getBalance()));
                } else {
                    umsAdminExport.setCurCreditBalance(x.getCreditBalance());
                }

//                userAddressExport.setIsValid(BooleanUtil.isTrue(x.getIsValid())?"是":"否");
//                userAddressExport.setIsResidential(BooleanUtil.isTrue(x.getIsValid())?"是":"否");
                return umsAdminExport;

            }).collect(Collectors.toList());

            String s = staticController.exports(balanceLogExports, UmsAdminExport.class);
            return CommonResult.success(s);
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult buildToken(Integer id) {
        // 不可以切换管理员
        List<UmsRole> targetRoles = getRoleList(id);
        if (targetRoles.stream().map(UmsRole::getId).filter(Objects::nonNull).collect(Collectors.toSet()).contains(Roles.ADMIN.getValue())) {
            return CommonResult.failed("非法操作");
        }
        String token = generateTokenByUserId(id);
        return CommonResult.success(token);
    }

    @Override
    public CommonResult releaseEarnest(UserReleaseEarnestRequest request) {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            Integer userId = request.getUserId();
            BigDecimal earnestBalance = request.getEarnest();

            LambdaQueryWrapper<UmsAdmin> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UmsAdmin::getId, userId);
            queryWrapper.last("FOR UPDATE");
            UmsAdmin user = getOne(queryWrapper);
            if (user == null) {
                Asserts.fail("未找到用户");
            }

            if (BigDecimal.ZERO.compareTo(earnestBalance) > -0) {
                Asserts.fail("没有保证金可释放");
            }

            // 增加余额
            UpdateWrapper<UmsAdmin> updateWrapper = new UpdateWrapper<UmsAdmin>().eq("id", user.getId()).setSql("balance=balance+earnest_balance");
            if (!update(updateWrapper)) {
                Asserts.fail("更新用户余额失败");
            }
            UpdateWrapper<UmsAdmin> updateWrapper2 = new UpdateWrapper<UmsAdmin>().eq("id", user.getId()).setSql("earnest_balance= earnest_balance-" + earnestBalance);
            if (!update(updateWrapper2)) {
                Asserts.fail("更新用户保证金失败");
            }
            BigDecimal balance = user.getBalance();

            BigDecimal afterBalance = balance.add(earnestBalance);
            // 增加余额变动明细
            BalanceLog log = new BalanceLog();
            log.setUserId(userId);
            log.setAfterValue(afterBalance);
            log.setChangeValue(earnestBalance);
            log.setRemark("保证金释放");
            log.setType(BalanceLogType.EARNEST_RELEASE);
            log.setSellerId(user.getSellerId());
            log.setBalanceType(BalanceType.BALANCE);
            String orderNo = request.getOrderNo();
            log.setOrderNo(orderNo);

            List<BalanceLog.Detail> details = new ArrayList<>();
            details.add(new BalanceLog.Detail("保证金释放", earnestBalance.toString()));
            if (!balanceLogService.save(log)) {
                Asserts.fail("写入保证金释放明细失败");
            }
            // 如果上述操作都成功，那么提交事务
            transactionManager.commit(status);
        } catch (Exception ex) {
            // 如果出现异常，那么回滚事务
            transactionManager.rollback(status);
            throw ex;
        }

        return CommonResult.success();
    }

    @Override
    public void releaseDeposit(List<UserReleaseEarnestRequest> st) {
        if (CollectionUtil.isNotEmpty(st)) {
            TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
            try {
                List<BalanceLog> logs = new ArrayList<>(st.size());
                for (UserReleaseEarnestRequest request : st) {
                    UmsAdmin user = lambdaQuery().eq(UmsAdmin::getId, request.getUserId())
                            .last("FOR UPDATE")
                            .one();
                    if (ObjectUtils.isNotEmpty(user)) {
                        if (user.getEarnestBalance().compareTo(request.getEarnest()) < 0) {
                            throw new RuntimeException();
                        }
                        BigDecimal balance = user.getBalance();
                        //更新余额，更新用户保证金
                        boolean isFlag = lambdaUpdate().eq(UmsAdmin::getId, request.getUserId())
                                .setSql("balance = balance + " + request.getEarnest())
                                .setSql("earnest_balance = earnest_balance -" + request.getEarnest())
                                .update();
                        if (isFlag) {
                            //记录余额变动明细


                            BalanceLog log = new BalanceLog();
                            log.setUserId(request.getUserId());
                            log.setAfterValue(request.getEarnest().add(balance));
                            log.setChangeValue(request.getEarnest());
                            log.setRemark("保证金释放");
                            log.setType(BalanceLogType.EARNEST_RELEASE);
                            log.setSellerId(user.getSellerId());
                            log.setBalanceType(BalanceType.BALANCE);
                            String orderNo = request.getOrderNo();
                            log.setOrderNo(orderNo);
                            List<BalanceLog.Detail> details = new ArrayList<>();
                            details.add(new BalanceLog.Detail("保证金释放", request.getEarnest().toString()));
                            log.setDetails(new Gson().toJson(details));
                            logs.add(log);
                        }
                    }
                }
                if (CollectionUtil.isNotEmpty(logs)) {
                    balanceLogService.saveBatch(logs);
                }
                transactionManager.commit(status);
            } catch (Exception ex) {
                transactionManager.rollback(status);
                throw ex;
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void releaseDepositByCancelAudit(Integer userId, BigDecimal rate, BigDecimal earnest, String orderNo) {
        //查询该笔订单是否存在支付记录
        UmsAdmin user = lambdaQuery().eq(UmsAdmin::getId, userId)
                .last("FOR UPDATE")
                .one();
        if (ObjectUtils.isNotEmpty(user)) {
            if (user.getEarnestBalance().compareTo(earnest) < 0) {
                throw new RuntimeException();
            }
            BigDecimal balance = user.getBalance();
            //更新余额，更新用户保证金，余额
            boolean isFlag = lambdaUpdate().eq(UmsAdmin::getId, userId)
                    .setSql("balance = balance + " + earnest.add(rate))
                    .setSql("earnest_balance = earnest_balance -" + earnest)
                    .update();
            if (isFlag) {
                //记录余额变动明细
                BalanceLog log = new BalanceLog();
                log.setUserId(userId);
                log.setAfterValue(balance.add(earnest).add(rate));
                log.setChangeValue(earnest.add(rate));
                log.setRemark("退款");
                log.setType(BalanceLogType.REFUND);
                log.setSellerId(user.getSellerId());
                log.setBalanceType(BalanceType.BALANCE);
                log.setOrderNo(orderNo);
                List<BalanceLog.Detail> details = new ArrayList<>();
                details.add(new BalanceLog.Detail("寄件", rate.toString()));
                details.add(new BalanceLog.Detail("保证金释放", earnest.toString()));
                log.setDetails(new Gson().toJson(details));
                balanceLogService.save(log);
            }
        }
    }

    @Override
    @Transactional
    public CommonResult releaseEarnestAllByUserId(Integer userId) {


        //查询当前用户的订单信息
        List<Order> orders = orderService.lambdaQuery().gt(Order::getEarnest, new BigDecimal("0")).eq(Order::getUserId, userId).list();
        if (CollectionUtil.isNotEmpty(orders)) {
            //计算保证金总额
            UmsAdmin user = lambdaQuery().eq(UmsAdmin::getId, userId)
                    .last("FOR UPDATE")
                    .one();
            BigDecimal totalAmount = orders.stream().map(Order::getEarnest).reduce(BigDecimal.ZERO, BigDecimal::add);
            if (totalAmount.compareTo(user.getEarnestBalance()) != 0) {
                return CommonResult.failed("保证金信息有误！！！");
            }
            if (ObjectUtils.isNotEmpty(user)) {
                if (user.getEarnestBalance().compareTo(new BigDecimal("0")) > 0) {
                    //用户当前余额
                    BigDecimal nowBalance = user.getBalance();
                    //更新用户余额和保证金
                    boolean isFlag = lambdaUpdate().eq(UmsAdmin::getId, userId)
                            .setSql("balance = balance + " + user.getEarnestBalance())
                            .set(UmsAdmin::getEarnestBalance, 0)
                            .update();
                    if (isFlag) {
                        List<BalanceLog> logs = new ArrayList<>(orders.size());
                        for (Order order : orders) {
                            nowBalance = nowBalance.add(order.getEarnest());
                            BalanceLog log = new BalanceLog();
                            log.setUserId(userId);
                            log.setAfterValue(nowBalance);
                            log.setOrderNo(order.getOrderNo());
                            log.setChangeValue(order.getEarnest());
                            log.setType(BalanceLogType.EARNEST_RELEASE);
                            log.setRemark("一键释放保证金");
                            if (ObjectUtil.isNotEmpty(user.getSellerId())) {
                                log.setSellerId(user.getSellerId());
                            }
                            log.setBalanceType(BalanceType.BALANCE);
                            List<BalanceLog.Detail> details = new ArrayList<>(1);
                            details.add(new BalanceLog.Detail("保证金释放", order.getEarnest().toString()));
                            log.setDetails(new Gson().toJson(details));
                            logs.add(log);

                            //修改订单信息
                            order.setEarnest(new BigDecimal("0"));
                            order.setEarnestTime(LocalDateTime.now());
                        }
                        //todo 后续可能需要考虑list过大问题
                        balanceLogService.saveBatch(logs);
                        orderService.updateBatchById(orders);
                    }
                }
            }
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult sendMail(SendMail mail) {
        //查询所有注册的用户信息
        //List<UmsAdmin> list = lambdaQuery().select(UmsAdmin::getEmail).eq(UmsAdmin::getStatus, 1).isNotNull(UmsAdmin::getEmail).list();
        List<UmsAdmin> list = lambdaQuery().select(UmsAdmin::getEmail).eq(UmsAdmin::getStatus, 1).isNotNull(UmsAdmin::getEmail).eq(UmsAdmin::getId, 69).list();
        if (CollectionUtil.isNotEmpty(list)) {
            List<InternetAddress> emailAddresses = new ArrayList<>(list.size());
            for (UmsAdmin umsAdmin : list) {
                try {
                    //发送邮件
                    InternetAddress address = new InternetAddress(umsAdmin.getEmail());
                    emailAddresses.add(address);
                } catch (AddressException e) {
                    e.printStackTrace();
                }
            }
            // 将列表转换为数组
            InternetAddress[] internetAddresses = emailAddresses.toArray(new InternetAddress[0]);
            try {
                Session session = JavaMailUntil.createSession();
                //2.创建邮件对象
                MimeMessage message = new MimeMessage(session);
                //设置邮件主题
                message.setSubject(mail.getSubject());
                //设置邮件内容
                message.setText(mail.getText());
                //设置发件人
                message.setFrom(new InternetAddress("15364494269@163.com"));
                //设置收件人
                //message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("2640848906@qq.com"));
                //设置抄送人
                message.setRecipients(MimeMessage.RecipientType.CC, internetAddresses);
                //3.发送邮件
                Transport.send(message);
            } catch (AddressException e) {
                e.printStackTrace();
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<StatisticsOrderDto> getSalesAndOrdersByRole() {
        UmsAdmin userInfo = AdminUserUtil.getUserInfo();
        // 当前系统是单角色系统
        List<Integer> roleIds = adminRoleRelationService.list(new LambdaQueryWrapper<UmsAdminRoleRelation>()
                .eq(UmsAdminRoleRelation::getAdminId, userInfo.getId())
                .select(UmsAdminRoleRelation::getRoleId)).stream().map(UmsAdminRoleRelation::getRoleId).collect(Collectors.toList());
        List<UmsRole> adminRoles = roleMapper.selectList(new LambdaQueryWrapper<UmsRole>()
                .in(UmsRole::getId, roleIds).eq(UmsRole::getStatus, ChannelStatus.ON)
                .select(UmsRole::getName, UmsRole::getId));
        List<Integer> orderNormalStatus = Stream.of(OrderStatus.values()).filter(orderStatus ->
                !(orderStatus.equals(OrderStatus.DRAFT) ||
                        orderStatus.equals(OrderStatus.CANCEL_ING) ||
                        orderStatus.equals(OrderStatus.CANCEL) ||
                        orderStatus.equals(OrderStatus.FAILURE) ||
                        orderStatus.equals(OrderStatus.VOIDED))).map(OrderStatus::getValue).collect(Collectors.toList());

        StatisticsOrderDto resultData = new StatisticsOrderDto();
        List<UserSumAmountDto> dayPieData = Lists.newArrayList();

        // 周折现数据 需要每天的数据 这里不用
        //List<UserWeekSumAmountDto> weekLineData = Lists.newArrayList();
        // 每个用户当前周每天数据
        List<UserWeekDaySumAmountDto> userWeekDayLineData = Lists.newArrayList();

        // 先不考虑多角色 直接addAll
        // test code start
        /*List<UmsRole> adminRoles = Lists.newArrayList();
        UmsRole umsRole = new UmsRole();
        umsRole.setId(Roles.SALES.getValue());
        adminRoles.add(umsRole);
        userInfo.setId(79);*/
        // test code end
        adminRoles.forEach(role -> {
            if (role.getId().equals(Roles.ADMIN.getValue())) {
                // 超级管理员 登录user如果是管理员，查看当日消费前十的用户的消费和订单数，
                List<UserSumAmountDto> topRateByUserDate = orderService.getTopRateByUserDate(orderNormalStatus);
                dayPieData.addAll(topRateByUserDate);

                // 所有用户一周的数据 需要每天的数据 这里不用
                /*List<UserWeekSumAmountDto> weekTopRateByUserDate = orderService.getWeekTopRateByUserData(orderNormalStatus).stream().peek(userWeekSumAmountDto -> {
                    userWeekSumAmountDto.setWeek(userWeekSumAmountDto.getWeek()-1);
                    if (userWeekSumAmountDto.getWeek().equals(0)) {
                        userWeekSumAmountDto.setWeek(7);
                    }
                }).sorted((UserWeekSumAmountDto u1, UserWeekSumAmountDto u2) -> {
                    return u1.getWeek().compareTo(u2.getWeek());
                }).collect(Collectors.toList());
                weekLineData.addAll(weekTopRateByUserDate);*/

                // 每个用户当前周每天的数据
                // 24-07-23 需求变更 展示当日消费前十用户数据
                // 需求变更 显示周几改为yyyy-mm-dd的数据
                List<UserWeekDaySumAmountDto> allUserWeekDayLineData = orderService.getWeekTopRateByUserEveryDay(orderNormalStatus);
                userWeekDayLineData.addAll(allUserWeekDayLineData);

            } else if (role.getId().equals(Roles.SALES.getValue())) {
                // 销售 如果user是销售，查看自己的用户的当日消费图和折线图，
                List<UserSumAmountDto> topRateByUserDate = orderService.getUserAmountNum(userInfo.getId(), orderNormalStatus);
                dayPieData.addAll(topRateByUserDate);

                // 需要每天的数据 这里不用
                /*List<UserWeekSumAmountDto> weekTopRateByUserDate = orderService.getUserWeekAmountNum(userInfo.getId(), orderNormalStatus).stream().peek(userWeekSumAmountDto -> {
                    userWeekSumAmountDto.setWeek(userWeekSumAmountDto.getWeek()-1);
                    if (userWeekSumAmountDto.getWeek().equals(0)) {
                        userWeekSumAmountDto.setWeek(7);
                    }
                }).sorted((UserWeekSumAmountDto u1, UserWeekSumAmountDto u2) -> {
                    return u1.getWeek().compareTo(u2.getWeek());
                }).collect(Collectors.toList());
                weekLineData.addAll(weekTopRateByUserDate);*/

                // 销售关联的每个用户当前周每个人每天的订单统计数据
                // 24-07-23 需求变更 展示当日消费前十用户数据
                // 需求变更 显示周几改为yyyy-mm-dd的数据
                List<UserWeekDaySumAmountDto> allUserWeekDayLineData = orderService.getUserWeekDayAmountNum(userInfo.getId(), orderNormalStatus);
                userWeekDayLineData.addAll(allUserWeekDayLineData);

            } else if (role.getId().equals(Roles.USER.getValue())) {
                // 普通用户 如果user是普通 用户就查看自己的消费和订单数
                List<UserSumAmountDto> topRateByUserDate = orderService.getAmountNum(userInfo.getId(), orderNormalStatus);
                dayPieData.addAll(topRateByUserDate);

                // 需要每天的数据 这里不用
                /*List<UserWeekSumAmountDto> weekTopRateByUserDate = orderService.getWeekAmountNum(userInfo.getId(), orderNormalStatus).stream().peek(userWeekSumAmountDto -> {
                    userWeekSumAmountDto.setWeek(userWeekSumAmountDto.getWeek()-1);
                    if (userWeekSumAmountDto.getWeek().equals(0)) {
                        userWeekSumAmountDto.setWeek(7);
                    }
                }).sorted((UserWeekSumAmountDto u1, UserWeekSumAmountDto u2) -> {
                    return u1.getWeek().compareTo(u2.getWeek());
                }).collect(Collectors.toList());
                weekLineData.addAll(weekTopRateByUserDate);*/

                // 当前用户当前周每天订单统计数据
                // 需求变更 显示周几改为yyyy-mm-dd的数据
                List<UserWeekDaySumAmountDto> allUserWeekDayLineData = orderService.getWeekDayAmountNum(userInfo, orderNormalStatus);
                userWeekDayLineData.addAll(allUserWeekDayLineData);
            }
        });
        resultData.setDayPieData(dayPieData);
        //resultData.setWeekLineData(weekLineData);
        resultData.setUserWeekDayLineData(userWeekDayLineData);
        return CommonResult.success(resultData);
    }

    /**
     * @param
     * @Author: hhp
     * @Description: 统计 各销售名下客户当日总打单金额和利润
     * @Data: 2024/7/23 10:29
     * @return: com.jinke.api.common.api.CommonResult<java.util.List < com.jinke.api.modules.ums.dto.SellerUserGroupDto>>
     * @throws:
     **/
    @Override
    public CommonResult<List<SellerUserGroupDto>> getSellerUserOrderStatistics(SellerUserDayParam sellerUserDayParam) {
        // 柱状图---统计各个销售名下客户日总打单金额和利润
        List<Integer> allSellers = Lists.newArrayList();
        if (ObjectUtil.isNotNull(sellerUserDayParam.getSellerId())) {
            allSellers.add(sellerUserDayParam.getSellerId().intValue());
        } else {
            // 拿到所有销售的id
            allSellers = adminRoleRelationService.list(new LambdaQueryWrapper<UmsAdminRoleRelation>()
                    .eq(UmsAdminRoleRelation::getRoleId, Roles.SALES.getValue())
                    .select(UmsAdminRoleRelation::getAdminId)).stream().map(UmsAdminRoleRelation::getAdminId).collect(Collectors.toList());
        }
        // 拿到所有销售关联的所有用户
        List<UmsAdmin> allSellerUsers = Lists.newArrayList();
        if (CollUtil.isNotEmpty(allSellers)) {
            /*allSellerUsers = this.list(new LambdaQueryWrapper<UmsAdmin>()
                    .in(UmsAdmin::getSellerId, allSellers).eq(UmsAdmin::getStatus, ChannelStatus.ON)
                    .select(UmsAdmin::getId, UmsAdmin::getSellerId, UmsAdmin::getRealName, UmsAdmin::getUsername, UmsAdmin::getEmail));*/
            // 禁用用户的业绩也算
            allSellerUsers = this.list(new LambdaQueryWrapper<UmsAdmin>()
                    .in(UmsAdmin::getSellerId, allSellers)
                    .select(UmsAdmin::getId, UmsAdmin::getSellerId, UmsAdmin::getRealName, UmsAdmin::getUsername, UmsAdmin::getEmail));
        }
        // 正常订单状态
        List<Integer> orderNormalStatus = Stream.of(OrderStatus.values()).filter(orderStatus ->
                !(orderStatus.equals(OrderStatus.DRAFT) ||
                        orderStatus.equals(OrderStatus.CANCEL_ING) ||
                        orderStatus.equals(OrderStatus.CANCEL) ||
                        orderStatus.equals(OrderStatus.FAILURE) ||
                        orderStatus.equals(OrderStatus.VOIDED))).map(OrderStatus::getValue).collect(Collectors.toList());

        // 拿到所有销售关联的用户的当日订单统计数据
        if (CollUtil.isNotEmpty(allSellerUsers)) {
            // 拿到所有销售关联的用户的当日订单统计数据
            List<UserDayOrderProfitDto> userDayOrderProfitDtos = orderService.getAllSellerUserDay(allSellerUsers, orderNormalStatus);

            if (CollUtil.isNotEmpty(userDayOrderProfitDtos)) {
                // 数据处理
                Map<Integer, List<UmsAdmin>> sellerUserGroup = allSellerUsers.stream().collect(Collectors.groupingBy(UmsAdmin::getSellerId));
                List<SellerUserGroupDto> usersStatistics = Lists.newArrayList();
                sellerUserGroup.forEach((sellerId, umsAdmins) -> {
                    SellerUserGroupDto sellerUserGroupDto = new SellerUserGroupDto();
                    sellerUserGroupDto.setSellerId(Long.valueOf(sellerId));
                    sellerUserGroupDto.setUserOrders(umsAdmins.stream().map(item -> {
                        /*UserDayOrderProfitDto userDayOrderProfitDto = userDayOrderProfitDtos.stream().filter(userOrderData -> userOrderData.getUserId().equals(Long.valueOf(item.getId()))).findFirst().orElse(new UserDayOrderProfitDto());
                        userDayOrderProfitDto.setUserName(StrUtil.isNotBlank(item.getRealName()) ? item.getRealName() : item.getUsername());
                        userDayOrderProfitDto.setEmail(item.getEmail());*/
                        UserDayOrderProfitDto userDayOrderProfitDto = userDayOrderProfitDtos.stream().filter(userOrderData -> userOrderData.getUserId().equals(Long.valueOf(item.getId()))).findFirst().orElse(null);
                        if (Optional.ofNullable(userDayOrderProfitDto).isPresent()) {
                            userDayOrderProfitDto.setUserName(StrUtil.isNotBlank(item.getRealName()) ? item.getRealName() : item.getUsername());
                            userDayOrderProfitDto.setEmail(item.getEmail());
                        }
                        return userDayOrderProfitDto;
                    }).collect(Collectors.toList()).stream().filter(Objects::nonNull).collect(Collectors.toList()));
                    usersStatistics.add(sellerUserGroupDto);
                });
                return CommonResult.success(usersStatistics);
            }
        }
        return CommonResult.success(Lists.newArrayList());
    }

    /**
     * @param   choseMonth 前端传的月份
     * @Author: hhp
     * @Description:
     * @Data: 2024/7/24 11:14
     * @return: com.jinke.api.common.api.CommonResult<java.util.List < com.jinke.api.modules.ums.dto.SellerPerformanceDto>>
     * @throws:
     **/
    @Override
    public CommonResult<List<SellerPerformanceDto>> getSellerPerformanceStatistics(CompanySellerProfitParam choseMonth) {
        // 正常订单状态
        List<Integer> orderNormalStatus = Stream.of(OrderStatus.values()).filter(orderStatus ->
                !(orderStatus.equals(OrderStatus.DRAFT) ||
                        orderStatus.equals(OrderStatus.CANCEL_ING) ||
                        orderStatus.equals(OrderStatus.CANCEL) ||
                        orderStatus.equals(OrderStatus.FAILURE) ||
                        orderStatus.equals(OrderStatus.VOIDED))).map(OrderStatus::getValue).collect(Collectors.toList());
        Integer[] monthArray = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
        // 拿到总的月统计数据 1
        /*List<UserMonthStatisticsDto> sellerPerformanceStatistics = orderService.getSellerPerformanceStatistics(choseMonth, orderNormalStatus);*/
        // 直接根据订单的sellerID统计 上面是用订单user_id统计
        List<UserMonthStatisticsDto> sellerPerformanceStatistics = orderService.getSellerPerformanceStatisticsBySId(choseMonth, orderNormalStatus);
        // 拿到所有销售的id 1
        /*List<Integer> allSellers = adminRoleRelationService.list(new LambdaQueryWrapper<UmsAdminRoleRelation>()
                .eq(UmsAdminRoleRelation::getRoleId, Roles.SALES.getValue()).select(UmsAdminRoleRelation::getAdminId)).stream().map(UmsAdminRoleRelation::getAdminId).collect(Collectors.toList());
*/
        List<SellerPerformanceDto> sellerPerformanceDtos = Lists.newArrayList();

        String[] wzNiNaEmails = new String[]{WZ_EMAIL, WZ_EMAIL2, NINA_EMAIL};
        List<UmsAdmin> wzNiNaIds = this.list(new LambdaQueryWrapper<UmsAdmin>().in(UmsAdmin::getEmail, Arrays.asList(wzNiNaEmails)).eq(UmsAdmin::getStatus, ChannelStatus.ON).select(UmsAdmin::getId, UmsAdmin::getEmail));
        List<UmsAdmin> wzNiNaInfo = Optional.ofNullable(wzNiNaIds).orElse(Lists.newArrayList());
        // 拿到汪总的id
        Integer wzId = wzNiNaInfo.stream().filter(umsAdmin -> umsAdmin.getEmail().equals(WZ_EMAIL)).findFirst().orElse(new UmsAdmin()).getId();
        // 拿到nina的id
        Integer ninaId = wzNiNaInfo.stream().filter(umsAdmin -> umsAdmin.getEmail().equals(NINA_EMAIL)).findFirst().orElse(new UmsAdmin()).getId();
        // 拿到汪总第二个邮箱的id
        Integer wzId2 = wzNiNaInfo.stream().filter(umsAdmin -> umsAdmin.getEmail().equals(WZ_EMAIL2)).findFirst().orElse(new UmsAdmin()).getId();
        // sellerId
        // 统计的订单里的所有 seller_id
        List<Long> sellerIds = Optional.ofNullable(sellerPerformanceStatistics).orElse(Lists.newArrayList()).stream().map(UserMonthStatisticsDto::getSellerId).collect(Collectors.toList());
        // 看王总两个账号哪个没在统计数据里 单独拿该账号的统计数据
        boolean wzIdExitInStatistics = sellerIds.stream().anyMatch(sellerId -> sellerId.equals(Long.valueOf(wzId)));
        List<UserMonthStatisticsDto> wzSellerPerformanceStatistics = Lists.newArrayList();
        List<UserMonthStatisticsDto> wz2SellerPerformanceStatistics = Lists.newArrayList();
        if (!wzIdExitInStatistics) {
            // 统计数据里没WZ_EMAIL账号的统计数据 单独拿统计数据
            wzSellerPerformanceStatistics = Optional.ofNullable(
                    orderService.getSingleSellerPerformanceStatisticsBySId(choseMonth, orderNormalStatus, wzId)
            ).orElse(Lists.newArrayList());
        }
        BigDecimal wzTotalAmount = wzSellerPerformanceStatistics.stream().
                filter(item -> item.getSellerId().equals(Long.valueOf(wzId)))
                .collect(Collectors.toList()).stream()
                .map(UserMonthStatisticsDto::getTotalAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        boolean wzId2ExitInStatistics = sellerIds.stream().anyMatch(sellerId -> sellerId.equals(Long.valueOf(wzId2)));
        if (!wzId2ExitInStatistics) {
            // 统计数据里没WZ_EMAIL2账号的统计数据 单独拿统计数据
            wz2SellerPerformanceStatistics = Optional.ofNullable(
                    orderService.getSingleSellerPerformanceStatisticsBySId(choseMonth, orderNormalStatus, wzId2)
            ).orElse(Lists.newArrayList());
        }
        BigDecimal wz2TotalAmount = wz2SellerPerformanceStatistics.stream().
                filter(item -> item.getSellerId().equals(Long.valueOf(wzId2)))
                .collect(Collectors.toList()).stream()
                .map(UserMonthStatisticsDto::getTotalAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 将两个id放到所有销售id里后再去重
        sellerIds.add(Long.valueOf(wzId2));
        sellerIds.add(Long.valueOf(wzId));
        sellerIds = Optional.of(sellerIds.stream().distinct().collect(Collectors.toList())).orElse(Lists.newArrayList());

        if (CollectionUtil.isNotEmpty(sellerIds)) {
            // 拿到所有销售名字 和 邮箱
            List<UmsAdmin> allSellerInfos = this.list(new LambdaQueryWrapper<UmsAdmin>()
                    .in(UmsAdmin::getId, sellerIds).eq(UmsAdmin::getStatus, ChannelStatus.ON)
                    .select(UmsAdmin::getId, UmsAdmin::getRealName, UmsAdmin::getUsername, UmsAdmin::getEmail));

            // 拿到月分组数据
            Map<Integer, List<UserMonthStatisticsDto>> monthAllData = sellerPerformanceStatistics.stream().collect(Collectors.groupingBy(UserMonthStatisticsDto::getWhichMonth));

            //
            monthAllData.forEach((month, userMonthData) -> {
                SellerPerformanceDto sellerPerformanceDto = new SellerPerformanceDto();
                sellerPerformanceDto.setWhichMonth(month);

                // 汪总两个账号 admin@163.com和403379112@qq.com 这里只拿到了admin@163.com的数据，还需要403379112@qq.com的数据
                List<UserMonthStatisticsDto> sellerMonthData = Lists.newArrayList();
                allSellerInfos.forEach(sellerInfo -> {
                    if (sellerInfo.getId().equals(wzId)) {
                        //
                        if (!wzIdExitInStatistics) {
                            // 不在统计数据里 单独加一个
                            UserMonthStatisticsDto userMonthStatisticsDto = new UserMonthStatisticsDto();
                            // 当前销售关联的用户 当前月 总额
                            userMonthStatisticsDto.setSellerId(Long.valueOf(sellerInfo.getId()));
                            userMonthStatisticsDto.setSellerName(StrUtil.isNotBlank(sellerInfo.getRealName()) ? sellerInfo.getRealName() : sellerInfo.getUsername());
                            // 当前销售的数据
                            userMonthStatisticsDto.setTotalAmount(wzTotalAmount);
                            //userMonthStatisticsDto.setUserEmail();
                            userMonthStatisticsDto.setSellerEmail(sellerInfo.getEmail());
                            sellerMonthData.add(userMonthStatisticsDto);
                        } else {
                            UserMonthStatisticsDto userMonthStatisticsDto = new UserMonthStatisticsDto();
                            // 当前销售关联的用户 当前月 总额
                            userMonthStatisticsDto.setSellerId(Long.valueOf(sellerInfo.getId()));
                            userMonthStatisticsDto.setSellerName(StrUtil.isNotBlank(sellerInfo.getRealName()) ? sellerInfo.getRealName() : sellerInfo.getUsername());
                            // 当前销售的数据
                            userMonthStatisticsDto.setTotalAmount(userMonthData.stream().
                                    filter(item -> item.getSellerId().equals(Long.valueOf(sellerInfo.getId())))
                                    .collect(Collectors.toList()).stream()
                                    .map(UserMonthStatisticsDto::getTotalAmount)
                                    .reduce(BigDecimal.ZERO, BigDecimal::add));
                            //userMonthStatisticsDto.setUserEmail();
                            userMonthStatisticsDto.setSellerEmail(sellerInfo.getEmail());
                            sellerMonthData.add(userMonthStatisticsDto);
                        }
                    } else if (sellerInfo.getId().equals(wzId2)) {
                        if (!wzId2ExitInStatistics) {
                            // 不在统计数据里 单独加一个
                            UserMonthStatisticsDto userMonthStatisticsDto = new UserMonthStatisticsDto();
                            // 当前销售关联的用户 当前月 总额
                            userMonthStatisticsDto.setSellerId(Long.valueOf(sellerInfo.getId()));
                            userMonthStatisticsDto.setSellerName(StrUtil.isNotBlank(sellerInfo.getRealName()) ? sellerInfo.getRealName() : sellerInfo.getUsername());
                            // 当前销售的数据
                            userMonthStatisticsDto.setTotalAmount(wz2TotalAmount);
                            //userMonthStatisticsDto.setUserEmail();
                            userMonthStatisticsDto.setSellerEmail(sellerInfo.getEmail());
                            sellerMonthData.add(userMonthStatisticsDto);
                        } else {
                            UserMonthStatisticsDto userMonthStatisticsDto = new UserMonthStatisticsDto();
                            // 当前销售关联的用户 当前月 总额
                            userMonthStatisticsDto.setSellerId(Long.valueOf(sellerInfo.getId()));
                            userMonthStatisticsDto.setSellerName(StrUtil.isNotBlank(sellerInfo.getRealName()) ? sellerInfo.getRealName() : sellerInfo.getUsername());
                            // 当前销售的数据
                            userMonthStatisticsDto.setTotalAmount(userMonthData.stream().
                                    filter(item -> item.getSellerId().equals(Long.valueOf(sellerInfo.getId())))
                                    .collect(Collectors.toList()).stream()
                                    .map(UserMonthStatisticsDto::getTotalAmount)
                                    .reduce(BigDecimal.ZERO, BigDecimal::add));
                            //userMonthStatisticsDto.setUserEmail();
                            userMonthStatisticsDto.setSellerEmail(sellerInfo.getEmail());
                            sellerMonthData.add(userMonthStatisticsDto);
                        }
                    } else {
                        UserMonthStatisticsDto userMonthStatisticsDto = new UserMonthStatisticsDto();
                        // 当前销售关联的用户 当前月 总额
                        userMonthStatisticsDto.setSellerId(Long.valueOf(sellerInfo.getId()));
                        userMonthStatisticsDto.setSellerName(StrUtil.isNotBlank(sellerInfo.getRealName()) ? sellerInfo.getRealName() : sellerInfo.getUsername());
                        // 当前销售的数据
                        userMonthStatisticsDto.setTotalAmount(userMonthData.stream().
                                filter(item -> item.getSellerId().equals(Long.valueOf(sellerInfo.getId())))
                                .collect(Collectors.toList()).stream()
                                .map(UserMonthStatisticsDto::getTotalAmount)
                                .reduce(BigDecimal.ZERO, BigDecimal::add));
                        //userMonthStatisticsDto.setUserEmail();
                        userMonthStatisticsDto.setSellerEmail(sellerInfo.getEmail());
                        sellerMonthData.add(userMonthStatisticsDto);
                    }
                });

                List<UserMonthStatisticsDto> allStatisticsData = Lists.newArrayList();
                // 将汪总两个账号数据 合成 一个
                // 拿到两个账号数据
                List<UserMonthStatisticsDto> wz2Data = sellerMonthData.stream()
                        .filter(userMonthStatisticsDto ->
                                userMonthStatisticsDto.getSellerId().equals(Long.valueOf(wzId)) || userMonthStatisticsDto.getSellerId().equals(Long.valueOf(wzId2)))
                        .collect(Collectors.toList());
                // 拿到两个账号金额的和
                BigDecimal wzAllAmount = wz2Data.stream().map(UserMonthStatisticsDto::getTotalAmount)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                // 两个数据结合成一个数据
                UserMonthStatisticsDto wzMonthStatisticsDto = new UserMonthStatisticsDto();
                // 两个id随便一个id
                wzMonthStatisticsDto.setSellerId(Long.valueOf(wzId));
                //
                UmsAdmin wzInfo = Optional.of(allSellerInfos).orElse(Lists.newArrayList()).stream().filter(umsAdmin -> umsAdmin.getId().equals(wzId)).findFirst().orElse(new UmsAdmin());
                wzMonthStatisticsDto.setSellerName(StrUtil.isNotBlank(wzInfo.getRealName()) ? wzInfo.getRealName() : wzInfo.getUsername());
                // 当前销售的数据
                wzMonthStatisticsDto.setTotalAmount(wzAllAmount);
                //userMonthStatisticsDto.setUserEmail();
                wzMonthStatisticsDto.setSellerEmail(wzInfo.getEmail());

                allStatisticsData.add(wzMonthStatisticsDto);
                sellerMonthData.stream()
                        .filter(userMonthStatisticsDto ->
                                !userMonthStatisticsDto.getSellerId().equals(Long.valueOf(wzId)) && !userMonthStatisticsDto.getSellerId().equals(Long.valueOf(wzId2)))
                        .forEach(allStatisticsData::add);

                // 当前月 所有人总的业绩 公司业绩
                // change 公司业绩只拿 汪总和nina的totalAmount的和
                /*UserMonthStatisticsDto userMonthStatisticsDto = new UserMonthStatisticsDto();
                userMonthStatisticsDto.setSellerId(0l);
                // TODO 待提取到公共参数
                userMonthStatisticsDto.setSellerName("公司");
                userMonthStatisticsDto.setWhichMonth(month);
                userMonthStatisticsDto.setTotalAmount(userMonthData.stream().map(UserMonthStatisticsDto::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
                sellerMonthData.add(userMonthStatisticsDto);*/

                // change 公司业绩 拆分成 汪总和nina两个人的数据
                /*UserMonthStatisticsDto wzMonthStatisticsDto = new UserMonthStatisticsDto();
                wzMonthStatisticsDto.setSellerId(0l);
                // TODO 待提取到公共参数
                wzMonthStatisticsDto.setSellerName(WZ_EMAIL);
                wzMonthStatisticsDto.setSellerEmail(WZ_EMAIL);
                wzMonthStatisticsDto.setWhichMonth(month);
                // change 只拿汪总和nina的金额
                BigDecimal wzMonthAmount = userMonthData.stream().filter(item -> item.getSellerId().equals(Long.valueOf(wzId))).map(UserMonthStatisticsDto::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add);

                wzMonthStatisticsDto.setTotalAmount(wzMonthAmount);
                sellerMonthData.add(wzMonthStatisticsDto);

                // change 公司业绩 拆分成 汪总和nina两个人的数据
                UserMonthStatisticsDto ninaMonthStatisticsDto = new UserMonthStatisticsDto();
                ninaMonthStatisticsDto.setSellerId(-1l);
                // TODO 待提取到公共参数
                ninaMonthStatisticsDto.setSellerName(NINA_EMAIL);
                ninaMonthStatisticsDto.setSellerEmail(NINA_EMAIL);
                ninaMonthStatisticsDto.setWhichMonth(month);
                // change 只拿汪总和nina的金额
                BigDecimal ninaAmount = userMonthData.stream().filter(item -> item.getSellerId().equals(Long.valueOf(ninaId))).map(UserMonthStatisticsDto::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add);

                ninaMonthStatisticsDto.setTotalAmount(ninaAmount);
                sellerMonthData.add(ninaMonthStatisticsDto);*/

                //sellerPerformanceDto.setStatistics(sellerMonthData);
                sellerPerformanceDto.setStatistics(allStatisticsData);
                sellerPerformanceDtos.add(sellerPerformanceDto);
            });
            // 如果传过来参数月份为空 需要拿到所有月份数据
            if (ObjectUtil.isEmpty(choseMonth)) {
                // 需要手动加空数据的月份
                List<Integer> needAddEmptyMonths = Arrays.stream(monthArray).filter(month -> sellerPerformanceDtos.stream().noneMatch(item -> item.getWhichMonth().equals(month))).collect(Collectors.toList());
                needAddEmptyMonths.forEach(month -> {
                    SellerPerformanceDto sellerPerformanceDto = new SellerPerformanceDto();
                    sellerPerformanceDto.setWhichMonth(month);
                    sellerPerformanceDto.setStatistics(Lists.newArrayList());
                    sellerPerformanceDtos.add(sellerPerformanceDto);
                });
            }
        }
        return CommonResult.success(sellerPerformanceDtos.stream().sorted((item1, item2) -> item1.getWhichMonth().compareTo(item2.getWhichMonth())).collect(Collectors.toList()));
    }

    @Override
    public CommonResult<List<SellerVo>> getAllEnableSellers() {
        // 拿到所有销售的id
        List<Integer> allSellers = adminRoleRelationService.list(new LambdaQueryWrapper<UmsAdminRoleRelation>()
                .eq(UmsAdminRoleRelation::getRoleId, Roles.SALES.getValue()).select(UmsAdminRoleRelation::getAdminId)).stream().map(UmsAdminRoleRelation::getAdminId).collect(Collectors.toList());
        // 拿到所有销售名字
        /*List<UmsAdmin> allSellerInfos = this.list(new LambdaQueryWrapper<UmsAdmin>().in(UmsAdmin::getId, allSellers).eq(UmsAdmin::getStatus, ChannelStatus.ON)
                .select(UmsAdmin::getId, UmsAdmin::getRealName, UmsAdmin::getUsername, UmsAdmin::getEmail));*/
        // 需求变更 禁用的销售也显示
        List<UmsAdmin> allSellerInfos = this.list(new LambdaQueryWrapper<UmsAdmin>().in(UmsAdmin::getId, allSellers)//.eq(UmsAdmin::getStatus, ChannelStatus.ON)
                .select(UmsAdmin::getId, UmsAdmin::getRealName, UmsAdmin::getUsername, UmsAdmin::getEmail));
        return CommonResult.success(allSellerInfos.stream().map(user -> {
            return new SellerVo().setId(Long.valueOf(user.getId())).setSellerName(StrUtil.isNotBlank(user.getRealName()) ? user.getRealName() : user.getUsername()).setEmail(user.getEmail());
        }).collect(Collectors.toList()));
    }

    @Override
    public UmsAdmin overseasUserRegister(OverseasUserAddParam overseasUserAddParam) {
        UmsAdmin umsAdmin = new UmsAdmin();
        BeanUtils.copyProperties(overseasUserAddParam, umsAdmin);
        umsAdmin.setCreateTime(new Date());
        if (StrUtil.isBlank(overseasUserAddParam.getInvitationCode())) {
            umsAdmin.setInvitationCode(InvitationCodeUtil.create());
        }
        if (ObjectUtil.isNull(overseasUserAddParam.getProfitRate())) {
            umsAdmin.setProfitRate(BigDecimal.valueOf(1));
        }
        umsAdmin.setStatus(ChannelStatus.ON.getValue());
        //查询是否有相同用户名的用户
        QueryWrapper<UmsAdmin> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UmsAdmin::getUsername, umsAdmin.getUsername());
        List<UmsAdmin> umsAdminList = list(wrapper);
        if (umsAdminList.size() > 0) {
            Asserts.fail("用户名已存在");
            return null;
        }
        if (list(new LambdaQueryWrapper<UmsAdmin>()
                .eq(UmsAdmin::getEmail, umsAdmin.getEmail())).size() > 0) {
            Asserts.fail("The email already exists");
            return null;
        }
        if (list(new LambdaQueryWrapper<UmsAdmin>()
                .eq(UmsAdmin::getPhone, umsAdmin.getPhone())).size() > 0) {
            Asserts.fail("The phone already exists");
            return null;
        }
        //将密码进行加密操作
        String encodePassword = passwordEncoder.encode(umsAdmin.getPassword());
        umsAdmin.setPassword(encodePassword);
        baseMapper.insert(umsAdmin);

        // 设置角色
        updateRole(umsAdmin.getId(), Arrays.asList(1));
        return umsAdmin;
    }


    /**
     * 根据汇总发消息
     *
     * @param dayEnd
     * @param startDay
     * @param noTrackList
     */
    @Override
    public void checkSummaryThenSendMSG(String dayEnd, String startDay, List<TrackSummaryVO> noTrackList) {
        // 收集成set set集合元素不能重复 自带去重
        Set<Integer> userIds = Optional.ofNullable(noTrackList).orElse(Lists.newArrayList()).stream().map(TrackSummaryVO::getUserId).collect(Collectors.toSet());
        List<UserOrderCountVO> userOrderCounts = Lists.newArrayList();
        if (!userIds.isEmpty()) {
            userOrderCounts = orderService.getCountGroupByUserId(userIds, startDay, dayEnd);
        }
        Map<Long, Integer> orderCountMap = userOrderCounts.stream().collect(Collectors.toMap(UserOrderCountVO::getUserId, UserOrderCountVO::getOrderCount));
        //相关用户
        List<Integer> userIdList = noTrackList.stream().map(TrackSummaryVO::getUserId).collect(Collectors.toList());
        //查询用户信息
        Map<Integer, SimpleUser> adminMap = this.getMaps(userIdList);
        for (TrackSummaryVO vo : noTrackList) {
            Integer userId = vo.getUserId();
            SimpleUser simpleUser = adminMap.get(userId);

            //组装消息
            SysMessageCreateRequest msg = new SysMessageCreateRequest();
            Integer totalOrderCount = orderCountMap.get(Long.valueOf(userId));
            //生成txt
            MockMultipartFile multipartFile = FileUtil.listToMultipartFile(vo.getNoinfoList());
            //上传返回下载链接
            String txtDownloadURL = ossUtil.upload("txtDownloadURL", multipartFile);
            log.info("面单生成于" + startDay + "到" + dayEnd + "==================JOB统计轨迹下载url生成完=============");

            //拼接内容
            String realName = simpleUser.getRealName();
            String content = " 用户" + (realName != null ? realName : "") + "在这个时间段内总订单数：" + totalOrderCount
                    + "个，没有物流轨迹的有" + vo.getNoinfoNum() +
                    "个，无轨迹比率:" + MathTool.formatPercentage(vo.getNoinfoNum(), totalOrderCount)
                    + "个,物流号下载链接：  " + txtDownloadURL;

            msg.setContent(content);
            msg.setType(SysMessageType.NOTIFY);
            String title = "面单生成于" + startDay + "到" + dayEnd + "的订单中无轨迹的物流号";
            msg.setTitle(title);
            //生成消息
            Integer messageId = sysMessageService.createOneSysmsg(msg);
            //发站内信到人
            sysMessageService.sendMessageToUsers(userId, messageId);
            //前期给开发也发一份
            sysMessageService.sendMessageToUsers(183, messageId);

            log.info("面单生成于" + startDay + "到" + dayEnd + "==================JOB统计轨迹站内信发完=============");
            String toSend = "";
            try {
                if (CommonUtil.checkTC(userId)) {
                    toSend = Global.EMAIL_TACHENG;
                } else {
                    toSend = simpleUser.getEmail();
                }
                String finalToSend = toSend;
                Thread thread = new Thread(() -> {
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //发邮件
                    sysMessageService.sendMailToUs(content, null, title, finalToSend);
                });
                thread.start();


            } catch (Exception e) {
                log.info(e.getMessage() + "JOB统计轨迹发邮件出错" + toSend);
            }
            log.info("JOB统计轨迹发邮件成功" + toSend);
        }
        log.info("JOB统计轨迹发站内信+邮件结束");

    }
}
